﻿namespace Rally_MvvmC.Library
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using Newtonsoft.Json;
    using Rally_MvvmC.Library.Models;

    public class PageViewModelBase<DataStoreType, ViewModelClass, EntityClass> : PageViewModelBase<DataStoreType>
        where DataStoreType : IDataStore
        where ViewModelClass : ViewModelBase<DataStoreType, EntityClass>
        where EntityClass : class
    {
        public PageViewModelBase(ViewModelClass entity, Func<DataStoreType> createDataStore, string pageName)
            : base(createDataStore, pageName)
        {
            this.Entity = entity;
        }

        public ViewModelClass Entity { get; set; }

        public override ViewModelBase ViewModel
        {
            get
            {
                return this.Entity;
            }
        }
    }

    public class PageViewModelBase<DataStoreType> : PageViewModelBase
    where DataStoreType : IDataStore
    {
        private System.Lazy<DataStoreType> dataStore { get; set; }
        protected Func<DataStoreType> createDataStore;

        public PageViewModelBase(Func<DataStoreType> createDataStore, string pageUrl, ViewControllerBase viewControllerBase)
            : base(pageUrl, viewControllerBase)
        {
            this.createDataStore = createDataStore;
        }

        public PageViewModelBase(Func<DataStoreType> createDataStore, string pageUrl)
            : base(pageUrl)
        {
            this.createDataStore = createDataStore;
        }

        [JsonIgnore]
        public DataStoreType DataStore
        {

            get
            {
                if (dataStore == null && createDataStore != null)
                {
                    dataStore = new Lazy<DataStoreType>(createDataStore);
                }

                if (dataStore == null)
                {
                    throw new NullReferenceException("dataStore not initialized");
                }
                else
                {
                    return dataStore.Value;
                }
            }
        }
    }
        
    public class PageViewModelBase : IPageViewModel
    {
        private IPageInfoViewModel pageInfo;
        protected ViewControllerBase viewController;


        public PageViewModelBase(string pageUrl, ViewControllerBase viewController)
            : this(pageUrl)
        {
            this.viewController = viewController;
        }

        public PageViewModelBase(string pageUrl)
        {
            this.IsAuthenticated = WebMatrix.WebData.WebSecurity.IsAuthenticated;
            this.PageUrl = PageUrl;
        }

        public string PageUrl { get; set; }

        public bool IsProductionSite { get; set; }

        public bool IsAdministratorSite { get; set; }
        
        public bool IsAuthenticated { get; set; }
        
        public bool RequireSSL { get; set; }
        
        public string ReferUrl { get; set; }
        
        public string ReferUrlLink { get; set; }
        
        public string SecureRootUrl { get; set; }
        
        public string UnSecureRootUrl { get; set; }

        public IPageInfoViewModel PageInfo
        {
            get
            {
                if (this.pageInfo == null)
                {
                    this.pageInfo = new PageInfo();
                }

                return this.pageInfo;
            }

            set
            {
                if (this.pageInfo != value)
                {
                    this.pageInfo = value;
                }
            }
        }

        public virtual ViewModelBase ViewModel
        {
            get
            {
                return null;
            }
        }

        public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            var results = new List<ValidationResult>();
            return results;
        }
    }
}
